﻿using System;
using System.IO;
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using ExcelDataReader;
using System.Data;
using Newtonsoft.Json;
using System.Linq;
using System.Reflection;

namespace Client.Editor
{
    public class Export_GameConfig : EditorWindow
    {
        private string excelPath = "";
        private bool existPath = true;
        private string[] excelFiles;
        private string savePath;
        Assembly assembly;
        
        // 样式变量
        private GUIStyle titleStyle;
        private GUIStyle headerStyle;
        private GUIStyle boxStyle;
        private GUIStyle fileBoxStyle;
        private GUIStyle buttonStyle;
        private GUIStyle exportButtonStyle;
        private GUIStyle exportAllButtonStyle;
        private GUIStyle pathLabelStyle;
        private GUIStyle fileNameStyle;
        private GUIStyle sectionHeaderStyle;
        
        // 滚动位置
        private Vector2 mainScrollPosition;
        private Vector2 fileListScrollPosition;
        
        // 颜色定义
        private readonly Color primaryColor = new Color(0.1f, 0.4f, 0.8f);
        private readonly Color successColor = new Color(0.2f, 0.7f, 0.3f);
        private readonly Color warningColor = new Color(0.9f, 0.6f, 0.1f);
        private readonly Color backgroundColor = new Color(0.95f, 0.95f, 0.98f);
        
        public static void ShowWindow()
        {
            Export_GameConfig window = GetWindow<Export_GameConfig>("🎮 游戏配置导出工具");
            window.minSize = new Vector2(500, 400);
            window.Show();
        }

        private void OnEnable()
        {
            savePath = Path.Combine(Path.GetDirectoryName(Application.dataPath), "Assets", "BundlePackage", "pk_game", "config");
            assembly = Assembly.Load("Hotfix.Runtime");
            
            excelPath = Path.Combine(Path.GetDirectoryName(Application.dataPath), "Excel", "Game");
            if (!Directory.Exists(excelPath))
            {
                existPath = false;
            }
            else
            {
                excelFiles = Directory.GetFiles(excelPath, "*.xlsx");
                if (excelFiles == null || excelFiles.Length == 0)
                {
                    Debug.LogError($"Excel目录中不存在xlsx文件: {excelPath}");
                }
            }
        }
        
        private void InitializeStyles()
        {
            // 标题样式
            titleStyle = new GUIStyle(EditorStyles.largeLabel)
            {
                fontSize = 18,
                fontStyle = FontStyle.Bold,
                alignment = TextAnchor.MiddleCenter
            };
            titleStyle.normal.textColor = primaryColor;
            
            // 头部样式
            headerStyle = new GUIStyle(EditorStyles.label)
            {
                fontSize = 12,
                fontStyle = FontStyle.Italic,
                alignment = TextAnchor.MiddleCenter
            };
            headerStyle.normal.textColor = new Color(0.5f, 0.5f, 0.5f);
            
            // 主盒子样式
            boxStyle = new GUIStyle(GUI.skin.box)
            {
                padding = new RectOffset(20, 20, 15, 15),
                margin = new RectOffset(10, 10, 8, 8)
            };
            
            // 文件盒子样式
            fileBoxStyle = new GUIStyle(GUI.skin.box)
            {
                padding = new RectOffset(15, 15, 10, 10),
                margin = new RectOffset(3, 3, 3, 3)
            };
            
            // 基础按钮样式
            buttonStyle = new GUIStyle(GUI.skin.button)
            {
                fontSize = 12,
                fontStyle = FontStyle.Normal,
                fixedHeight = 32,
                padding = new RectOffset(15, 15, 5, 5),
                margin = new RectOffset(5, 5, 3, 3)
            };
            
            // 导出按钮样式
            exportButtonStyle = new GUIStyle(buttonStyle)
            {
                fixedHeight = 32,
                padding = new RectOffset(15, 15, 5, 5)
            };
            
            // 导出全部按钮样式
            exportAllButtonStyle = new GUIStyle(exportButtonStyle)
            {
                fontSize = 14,
                fontStyle = FontStyle.Bold,
                fixedHeight = 40,
                padding = new RectOffset(25, 25, 8, 8)
            };
            
            // 路径标签样式
            pathLabelStyle = new GUIStyle(EditorStyles.label)
            {
                wordWrap = true,
                alignment = TextAnchor.MiddleLeft,
                fontSize = 11,
                padding = new RectOffset(5, 5, 2, 2)
            };
            pathLabelStyle.normal.textColor = new Color(0.4f, 0.4f, 0.4f);
            
            // 文件名样式
            fileNameStyle = new GUIStyle(EditorStyles.label)
            {
                fontSize = 13,
                fontStyle = FontStyle.Bold,
                alignment = TextAnchor.MiddleLeft
            };
            fileNameStyle.normal.textColor = new Color(145/255.0f, 253/255.0f, 174/255.0f);
            
            // 分区标题样式
            sectionHeaderStyle = new GUIStyle(EditorStyles.label)
            {
                fontSize = 14,
                fontStyle = FontStyle.Bold,
                alignment = TextAnchor.MiddleLeft,
                padding = new RectOffset(0, 0, 5, 5)
            };
             sectionHeaderStyle.normal.textColor = new Color(0.6f, 0.3f, 0.1f);
        }

        private void OnGUI()
        {
            // 设置背景色
            GUI.backgroundColor = backgroundColor;
            
            // 初始化样式
            if (titleStyle == null)
            {
                InitializeStyles();
            }
            
            // 主滚动视图 - 用于整个窗口内容
            mainScrollPosition = EditorGUILayout.BeginScrollView(mainScrollPosition);
            {
                // 绘制标题区域
                DrawHeader();
                
                if (!existPath)
                {
                    DrawErrorBox();
                }
                else
                {
                    // 绘制内容区域
                    DrawContent();
                }
            }
            EditorGUILayout.EndScrollView();
            
            // 重置背景色
            GUI.backgroundColor = Color.white;
        }
        
        private void DrawHeader()
        {
            EditorGUILayout.Space(15);
            
            // 主标题
            EditorGUILayout.BeginVertical();
            EditorGUILayout.LabelField("🎮 游戏配置导出工具", titleStyle);
            EditorGUILayout.LabelField("将Excel配置表导出为游戏可用的数据格式", headerStyle);
            EditorGUILayout.EndVertical();
            
            EditorGUILayout.Space(20);
        }
        
        private void DrawErrorBox()
        {
            EditorGUILayout.BeginVertical(boxStyle);
            {
                EditorGUILayout.HelpBox($"❌ Excel目录不存在", MessageType.Error);
                
                EditorGUILayout.Space(10);
                EditorGUILayout.LabelField($"路径: {excelPath}", pathLabelStyle);
                EditorGUILayout.Space(15);
                
                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("关闭窗口", exportButtonStyle, GUILayout.Width(120)))
                {
                    Close();
                }
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
        }
        
        private void DrawContent()
        {
            // 路径信息区域
            DrawPathInfo();
            
            EditorGUILayout.Space(20);
            
            // 文件列表区域
            DrawFileListSection();
            
            EditorGUILayout.Space(15);
            
            // 操作按钮区域
            DrawActionButtons();
        }
        
        private void DrawPathInfo()
        {
            EditorGUILayout.BeginVertical(boxStyle);
            {
                EditorGUILayout.LabelField("📁 路径信息", sectionHeaderStyle);
                EditorGUILayout.Space(12);
                
                EditorGUILayout.BeginVertical(fileBoxStyle);
                {
                    EditorGUILayout.LabelField("Excel目录:", EditorStyles.boldLabel);
                    EditorGUILayout.Space(3);
                    EditorGUILayout.LabelField(excelPath, pathLabelStyle);
                }
                EditorGUILayout.EndVertical();
                
                EditorGUILayout.Space(8);
                
                EditorGUILayout.BeginVertical(fileBoxStyle);
                {
                    EditorGUILayout.LabelField("导出目录:", EditorStyles.boldLabel);
                    EditorGUILayout.Space(3);
                    EditorGUILayout.LabelField(savePath, pathLabelStyle);
                }
                EditorGUILayout.EndVertical();
                
                // 文件统计
                EditorGUILayout.Space(10);
                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                EditorGUILayout.LabelField($"发现 {excelFiles?.Length ?? 0} 个Excel文件", headerStyle);
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
        }
        
        private void DrawFileListSection()
        {
            EditorGUILayout.BeginVertical(boxStyle);
            {
                EditorGUILayout.LabelField("📊 配置文件列表", sectionHeaderStyle);
                EditorGUILayout.Space(10);
                
                if (excelFiles == null || excelFiles.Length == 0)
                {
                    EditorGUILayout.HelpBox("📭 未找到Excel文件", MessageType.Info);
                    return;
                }
                
                // 文件列表区域 - 使用固定高度和独立的滚动视图
                EditorGUILayout.BeginVertical(GUILayout.Height(250));
                {
                    // 文件列表滚动视图 - 使用独立的滚动位置变量
                    fileListScrollPosition = EditorGUILayout.BeginScrollView(fileListScrollPosition, GUI.skin.box);
                    {
                        foreach (var file in excelFiles)
                        {
                            DrawFileItem(file);
                        }
                    }
                    EditorGUILayout.EndScrollView();
                }
                EditorGUILayout.EndVertical();
            }
            EditorGUILayout.EndVertical();
        }
        
        private void DrawFileItem(string file)
        {
            EditorGUILayout.BeginVertical(fileBoxStyle);
            {
                EditorGUILayout.BeginHorizontal();
                {
                    // 文件图标和名称
                    EditorGUILayout.BeginVertical(GUILayout.Width(300));
                    {
                        EditorGUILayout.LabelField("📄 " + Path.GetFileName(file), fileNameStyle);
                        EditorGUILayout.LabelField(Path.GetDirectoryName(file), pathLabelStyle);
                    }
                    EditorGUILayout.EndVertical();
                    
                    GUILayout.FlexibleSpace();
                    
                    // 导出按钮 - 使用颜色而不是复杂的样式
                    Color originalColor = GUI.color;
                    GUI.color = new Color(0.2f, 0.6f, 0.9f);
                    if (GUILayout.Button("导出配置", exportButtonStyle, GUILayout.Width(100)))
                    {
                        ReadFile(file);
                        AssetDatabase.Refresh();
                        ShowNotification(new GUIContent($"✅ 已导出: {Path.GetFileName(file)}"));
                    }
                    GUI.color = originalColor;
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
            EditorGUILayout.Space(2);
        }
        
        private void DrawActionButtons()
        {
            EditorGUILayout.BeginVertical(boxStyle);
            {
                EditorGUILayout.LabelField("⚡ 批量操作", sectionHeaderStyle);
                EditorGUILayout.Space(15);
                
                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                
                // 导出全部按钮
                Color originalColor = GUI.color;
                GUI.color = successColor;
                if (GUILayout.Button($"🚀 导出全部文件 ({excelFiles?.Length ?? 0})", exportAllButtonStyle, GUILayout.Width(250)))
                {
                    if (EditorUtility.DisplayDialog("确认批量导出", 
                        $"确定要导出所有 {excelFiles.Length} 个Excel文件吗？\n\n这将覆盖现有的配置文件。", 
                        "确定导出", "取消"))
                    {
                        int successCount = 0;
                        foreach (var file in excelFiles)
                        {
                            try
                            {
                                ReadFile(file);
                                successCount++;
                            }
                            catch (Exception ex)
                            {
                                Debug.LogError($"导出失败 {Path.GetFileName(file)}: {ex.Message}");
                            }
                        }
                        AssetDatabase.Refresh();
                        ShowNotification(new GUIContent($"✅ 导出完成: {successCount}/{excelFiles.Length} 个文件"));
                    }
                }
                GUI.color = originalColor;
                
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
                
                EditorGUILayout.Space(5);
                
                // 刷新按钮
                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("🔄 刷新文件列表", buttonStyle, GUILayout.Width(150)))
                {
                    OnEnable(); // 重新初始化
                    Repaint();
                }
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
        }

        private void ReadFile(string file)
        {
            try
            {
                using (var stream = File.Open(file, FileMode.Open, FileAccess.Read))
                {
                    using (var reader = ExcelReaderFactory.CreateReader(stream))
                    {
                        var excelConfig = new ExcelDataSetConfiguration()
                        {
                            ConfigureDataTable = _ => new ExcelDataTableConfiguration()
                            {
                                UseHeaderRow = true,
                                FilterRow = rowReader => true,
                                FilterColumn = (rowReader, columnIndex) => true
                            }
                        };

                        var result = reader.AsDataSet(excelConfig);

                        if (result.Tables.Count == 0)
                            throw new InvalidOperationException("Excel文件中没有找到对应的表");

                        DataTable table = result.Tables[0];
                        string className = table.TableName;

                        Type targetType = assembly.GetType($"Client.Hotfix.{className}");
                        if (targetType == null)
                            throw new TypeLoadException($"未找到 Client.Hotfix.{className} 类");

                        DataRow typeRow = table.Rows[0];
                        DataRow descRow = table.Rows[1];
                        int dataStartRow = 2;

                        var columnDefinitions = new List<ColumnDefinition>();
                        for (int colIdx = 0; colIdx < table.Columns.Count; colIdx++)
                        {
                            string typeDef = typeRow[colIdx]?.ToString().Trim();
                            string fieldDesc = descRow[colIdx]?.ToString().Trim();

                            if (string.IsNullOrEmpty(typeDef) || string.IsNullOrEmpty(fieldDesc))
                                continue;

                            columnDefinitions.Add(new ColumnDefinition
                            {
                                index = colIdx,
                                type = typeDef,
                                property = table.Columns[colIdx].ColumnName
                            });
                        }

                        var propertyMap = new Dictionary<string, PropertyMapping>();
                        var properties = targetType.GetProperties(BindingFlags.Public | BindingFlags.Instance);

                        foreach (var colDef in columnDefinitions)
                        {
                            string potentialPropName = ExtractPropertyName(colDef.property);

                            PropertyInfo property = properties.FirstOrDefault(p =>
                                p.Name.Equals(potentialPropName, StringComparison.OrdinalIgnoreCase));

                            if (property != null)
                            {
                                propertyMap[colDef.property] = new PropertyMapping
                                {
                                    Property = property,
                                    ColumnDefinition = colDef,
                                    ExpectedType = ParseTypeDefinition(colDef.type)
                                };
                            }
                        }

                        var configs = new List<object>();
                        for (int rowIdx = dataStartRow; rowIdx < table.Rows.Count; rowIdx++)
                        {
                            DataRow row = table.Rows[rowIdx];
                            object configObj = Activator.CreateInstance(targetType);

                            foreach (var mapping in propertyMap)
                            {
                                string colName = mapping.Key;
                                PropertyMapping propMap = mapping.Value;
                                object cellValue = row[propMap.ColumnDefinition.index];

                                try
                                {
                                    object convertedValue = ConvertValueByTypeDefinition(cellValue, propMap.ExpectedType, propMap.Property.PropertyType);
                                    propMap.Property.SetValue(configObj, convertedValue);
                                }
                                catch (Exception ex)
                                {
                                    Debug.LogError($"行 {rowIdx + 1} 列 {colName} 转换失败: {ex.Message}");
                                }
                            }
                            configs.Add(configObj);
                        }

                        string json = JsonConvert.SerializeObject(configs, Formatting.Indented);
                        string outputPath = $"{savePath}/{className}.bytes";
                        
                        // 确保目录存在
                        Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
                        File.WriteAllText(outputPath, json, System.Text.Encoding.UTF8);
                        
                        Debug.Log($"✅ 成功导出: {Path.GetFileName(file)} -> {outputPath}");
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"❌ 导出文件 {Path.GetFileName(file)} 时出错: {ex.Message}");
                EditorUtility.DisplayDialog("导出错误", $"导出 {Path.GetFileName(file)} 时出错:\n{ex.Message}", "确定");
            }
        }

        // 其余的方法保持不变...
        private Type ParseTypeDefinition(string typeDef)
        {
            if (string.IsNullOrWhiteSpace(typeDef))
                return typeof(object);

            if (typeDef.StartsWith("<") && typeDef.EndsWith(">"))
            {
                string innerTypes = typeDef.Trim('<', '>');
                string[] typePair = innerTypes.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);

                if (typePair.Length == 2)
                {
                    Type keyType = ParseBasicType(typePair[0].Trim());
                    Type valueType = ParseBasicType(typePair[1].Trim());

                    if (keyType != null && valueType != null)
                    {
                        return typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
                    }
                }
            }
            else if (typeDef.EndsWith("[]"))
            {
                string elementTypeStr = typeDef.Substring(0, typeDef.Length - 2);
                Type elementType = ParseBasicType(elementTypeStr);
                return elementType?.MakeArrayType() ?? typeof(object);
            }

            return ParseBasicType(typeDef) ?? typeof(object);
        }

        private Type ParseBasicType(string typeDef)
        {
            switch (typeDef.ToLower().Trim())
            {
                case "int": return typeof(int);
                case "string": return typeof(string);
                case "bool": return typeof(bool);
                case "integer": return typeof(int);
                case "boolean": return typeof(bool);
                default: return null;
            }
        }

        private object ConvertValueByTypeDefinition(object value, Type expectedType, Type targetType)
        {
            if (value == null || value is DBNull)
                return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;

            string stringValue = value.ToString();

            try
            {
                if (expectedType == typeof(Dictionary<int, int>))
                    return ParseIntIntDictionary(stringValue);

                if (expectedType == typeof(Dictionary<int, string>))
                    return ParseIntStringDictionary(stringValue);

                if (expectedType == typeof(Dictionary<string, string>))
                    return ParseStringStringDictionary(stringValue);

                if (expectedType == typeof(Dictionary<int, bool>))
                    return ParseIntBoolDictionary(stringValue);

                if (targetType.IsArray)
                    return ConvertArray(stringValue, targetType.GetElementType());

                return Convert.ChangeType(value, targetType);
            }
            catch
            {
                Debug.LogError($"值转换失败: {stringValue} -> {targetType.Name}");
                return targetType.IsValueType ? Activator.CreateInstance(targetType) : null;
            }
        }

        private Dictionary<int, int> ParseIntIntDictionary(string input)
        {
            var dict = new Dictionary<int, int>();
            if (string.IsNullOrEmpty(input)) return dict;
            
            string[] s1 = input.Split(',');

            foreach (var item in s1)
            {
                string[] s2 = item.Replace("[","").Replace("]","").Split(":", StringSplitOptions.RemoveEmptyEntries);
                if(s2.Length == 2)
                {
                    dict.Add(int.Parse(s2[0]), int.Parse(s2[1]));
                }
            }

            return dict;
        }

        private Dictionary<int, string> ParseIntStringDictionary(string input)
        {
            var dict = new Dictionary<int, string>();
            if (string.IsNullOrEmpty(input)) return dict;
            
            string[] s1 = input.Split(',');
            foreach (var item in s1)
            {
                string[] s2 = item.Replace("[", "").Replace("]", "").Split(":", StringSplitOptions.RemoveEmptyEntries);
                if (s2.Length == 2)
                {
                    dict.Add(int.Parse(s2[0]), s2[1]);
                }
            }
            return dict;
        }

        private Dictionary<string, string> ParseStringStringDictionary(string input)
        {
            var dict = new Dictionary<string, string>();
            if (string.IsNullOrEmpty(input)) return dict;
            
            string[] s1 = input.Split(',');
            foreach (var item in s1)
            {
                string[] s2 = item.Replace("[", "").Replace("]", "").Split(":", StringSplitOptions.RemoveEmptyEntries);
                if (s2.Length == 2)
                {
                    dict.Add(s2[0], s2[1]);
                }
            }
            return dict;
        }

        private Dictionary<int, bool> ParseIntBoolDictionary(string input)
        {
            var dict = new Dictionary<int, bool>();
            if (string.IsNullOrEmpty(input)) return dict;
            
            string[] s1 = input.Split(',');
            foreach (var item in s1)
            {
                string[] s2 = item.Replace("[", "").Replace("]", "").Split(":", StringSplitOptions.RemoveEmptyEntries);
                if (s2.Length == 2)
                {
                    dict.Add(int.Parse(s2[0]),bool.Parse(s2[1]));
                }
            }
            return dict;
        }

        // 辅助类
        private class ColumnDefinition
        {
            public int index { get; set; }
            public string type { get; set; }
            public string property { get; set; }
        }

        private class PropertyMapping
        {
            public ColumnDefinition ColumnDefinition { get; set; }
            public PropertyInfo Property { get; set; }
            public Type ExpectedType { get; set; }
        }

        private string ExtractPropertyName(string fieldDesc)
        {
            return fieldDesc.Split(' ').FirstOrDefault()?.Trim();
        }

        private Array ConvertArray(string input, Type elementType)
        {
            if (string.IsNullOrWhiteSpace(input))
                return Array.CreateInstance(elementType, 0);

            var items = input.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
                            .Select(s => s.Trim())
                            .Where(s => !string.IsNullOrEmpty(s))
                            .ToArray();

            Array array = Array.CreateInstance(elementType, items.Length);

            for (int i = 0; i < items.Length; i++)
            {
                try
                {
                    array.SetValue(Convert.ChangeType(items[i], elementType), i);
                }
                catch
                {
                    array.SetValue(elementType.IsValueType ? Activator.CreateInstance(elementType) : null, i);
                }
            }

            return array;
        }
    }
}